This invention relates generally to computer systems and more particularly to a method and apparatus for constructing dispatch tables which enable transitive method override.
Inheritance is a major property of most object oriented programming systems. With inheritance, when a class is declared as a subclass of a superclass, that subclass automatically inherits all of the methods and attributes of the superclass. Thus, if class A has method M1 and attribute AT1, then class B, which is a subclass of class A, automatically inherits method M1 and attribute AT1. In addition to inheriting the methods and attributes of the superclass, the subclass may further comprise additional methods and attributes. Thus, for the example given above, class B may further comprise methods M2 and M3, and attributes AT2 and AT3.
In addition to inheriting and adding methods and attributes, some object oriented systems further allow subclasses to override the methods of the superclass. That is, the subclass is allowed to provide an implementation for an inherited method which is different from that provided by the superclass. This means that, for the example given above, subclass B may provide a different implementation for method M1 than that provided by superclass A. For example, the implementation for M1 provided by superclass A may draw a square whereas the implementation for method M1 provided by subclass B draws a circle. Thus, even though both methods have the same name, they may have different implementations. Which implementation is invoked depends upon the class of the object instance on which the method is invoked. If the method is invoked on a class A instance, then the implementation provided by class A will be invoked. If the method is invoked on a class B instance, then the implementation provided by class B will be invoked. Because there may be multiple implementations for any particular method, a determination will have to be made at runtime as to which implementation to invoke. The process of selecting which implementation to invoke at runtime is referred to as dynamic method dispatch.
In single inheritance systems where every subclass is able to access, and hence, override every method of a higher level class, the dynamic method dispatch process is relatively straightforward. However, some systems, such as the Java(trademark) programming system manufactured by Sun Microsystems, Inc. of Mountain View, Calif., implement constructs known as xe2x80x9cmodularity constructsxe2x80x9d which make it possible for a developer to restrict the accessibility of certain methods of certain classes to other classes. In the face of these accessibility restrictions, dynamic method dispatch is made much more complicated.
To elaborate, a modularity construct, sometimes referred to as a xe2x80x9cpackagexe2x80x9d in Java(trademark), provides a mechanism for grouping or encapsulating selected classes. The package construct makes it possible to limit access to the classes within a package by classes in other packages. More specifically, each method of each class within a package may be declared as xe2x80x9cpublicxe2x80x9d, xe2x80x9cprotectedxe2x80x9d, or xe2x80x9cpackage privatexe2x80x9d. If a method is declared public or protected (denoted as public/protected hereinafter), then it may be accessed, and hence overridden, by any subclass of that class. On the other hand, if a method is declared package private, then that method may be accessed and overridden by a subclass if and only if that subclass is within the same package. Subclasses outside the package may not access or override the method. FIG. 1 illustrates an example of such a situation. In FIG. 1, there is shown two packages, P1 and P2. Package P1 contains a class A having a package private method M1. package P2 contains a class B which extends A (meaning that B is a subclass of A) having a public/protected method M1. Because method M1 of class A is declared package private, and because class B is not in the same package as class A, class B will not be able to access or to override the method M1 of class A. Note that the package construct does not prevent class B from being a subclass of A, and hence, inheriting all of the attributes and methods of class A. The package only prevents class B from overriding the method M1 of class A. To enforce package constraints, it is a general rule that unless a subclass is within the same package as a higher level class that it wishes to override, it cannot override a package private method of the higher level class.
While on the surface, this general rule appears to effectively enforce the accessibility constraints imposed by modularity constructs, it can lead to some undesirable results, one of which is that of non-transitive method override. To illustrate how this non-transitive result can arise, suppose that a structure such as that shown in FIG. 2 is created, wherein there are two packages, P1 and P2. In package P1, there is a class A having a package private method M1. In the same package, there is a subclass B which extends A, having a public/protected method M1. In package P2, there is a subclass C which extends B, and which has a public/protected method M1. With such a structure, it is clear that method M1 of subclass B can access and hence override method M1 of class A (since B is in the same package as A). It is also clear that method M1 of class C can override the method M1 of class B (since method M1 of B is declared to be public/protected). According to the transitive property, if method M1 of C can override method M1 of B, and method M1 of B can override method M1 of A, then method M1 of C should be able to override method M1 of A. This is not the result in this example, however, because under the rule set forth above, M1 of C cannot override M1 of A because M1 of A is package private and C is not in the same package as A. Thus, as this example shows, strict adherence to this rule can lead to non-transitive results. Because this is a somewhat non-intuitive result, and because transitive method override is a desirable property, there is a need for an improved dynamic method dispatch mechanism which is both capable of enforcing the accessibility constraints of modular constructs and providing transitive method override.
The present invention provides a mechanism for constructing dispatch tables which may be used to perform dynamic method dispatch in a single inheritance system. As constructed, the dispatch tables enforce accessibility constraints imposed by modularity constructs while at the same time enabling transitive method override. According to one embodiment, a dispatch table for a class C (wherein C is within a package P and is a subclass of superclass S) is constructed as follows. First, the dispatch table for S is copied and is used as the starting point for the dispatch table of C. Then, for each locally declared method m in C, the following is performed.
The method m is checked to determine whether it has been marked as public/protected. If so, then the S dispatch table is checked for one or more public/protected entries corresponding to a method having the same name as method m. If one or more such entries is found, then for each such entry, the corresponding entry in the C dispatch table is overridden, and the index of the overridden entry is associated with method m. Otherwise, a new entry is allocated in the C dispatch table and is marked public/protected. Then, the index of the new entry is associated with method m. In addition, the S dispatch table is checked for one or more package private (private to package P) entries corresponding to a method having the same name as method m. If one or more such entries is found, then for each such entry, the corresponding entry in the C dispatch table is overridden and is marked public/protected.
If, on the other hand, the method m is marked as package private, then the S dispatch table is checked for one or more package private entries (private to package P) corresponding to a method having the same name as method m. If one or more such entries is found, then for each such entry, the corresponding entry in the C dispatch table is overridden, and the index of the overridden entry is associated with method m. Otherwise, a new entry is allocated in the C dispatch table and is marked package private. Then, the index of the new entry is associated with method m. In addition, the S dispatch table is checked for one or more public/protected entries corresponding to a method having the same name as method m. If one or more such entries is found, then for each such entry, the corresponding entry in the C dispatch table is overridden. However, that entry""s public/protected marking is maintained.
The above method is repeated for each method m of class C. Once all methods of class C have been processed, the dispatch table for class C will have been fully constructed. Constructed in the manner described, the dispatch table will support transitive method override.